package com.haohan.cloud.scm.message.core.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haohan.cloud.scm.api.constant.enums.message.MsgActionTypeEnum;
import com.haohan.cloud.scm.api.message.dto.SendInMailMessageDTO;
import com.haohan.cloud.scm.api.message.entity.InMailRecord;
import com.haohan.cloud.scm.api.message.entity.MessageRecord;
import com.haohan.cloud.scm.api.message.req.InMailModifyReq;
import com.haohan.cloud.scm.api.message.req.QueryMessageReq;
import com.haohan.cloud.scm.api.message.vo.MsgInfoVO;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.message.core.MessageCoreService;
import com.haohan.cloud.scm.message.service.InMailRecordService;
import com.haohan.cloud.scm.message.service.MessageRecordService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dy
 * @date 2020/1/14
 */
@Service
@AllArgsConstructor
public class MessageCoreServiceImpl implements MessageCoreService {
    private final MessageRecordService messageRecordService;
    private final InMailRecordService inMailService;

    @Override
    public IPage<MsgInfoVO> findPage(Page<MessageRecord> page, QueryMessageReq req) {
        MessageRecord msg = req.transTo();
        boolean flag = null != req.getStartDate() && null != req.getEndDate();
        IPage<MessageRecord> msgPage = messageRecordService.page(page, Wrappers.query(msg).lambda()
                // 按发送人查询时 系统消息全接受
                .and(CollUtil.isNotEmpty(req.getSenderUidSet()), q -> q
                        .in(MessageRecord::getSenderUid, req.getSenderUidSet())
                        .or()
                        .eq(MessageRecord::getMsgActionType, MsgActionTypeEnum.system)
                )
                .like(StrUtil.isNotEmpty(req.getTitle()), MessageRecord::getTitle, req.getTitle())
                .like(StrUtil.isNotEmpty(req.getSenderName()), MessageRecord::getSenderName, req.getSenderName())
                .like(StrUtil.isNotEmpty(req.getMessageSn()), MessageRecord::getMessageSn, req.getMessageSn())
                .apply(flag, "DATE(send_time) between {0} and {1}", req.getStartDate(), req.getEndDate())
                .orderByDesc(MessageRecord::getSendTime)
        );
        IPage<MsgInfoVO> result = new Page<>(msgPage.getCurrent(), msgPage.getSize(), msgPage.getTotal());
        if (msgPage.getRecords().size() > 0) {
            result.setRecords(msgPage.getRecords().stream()
                    .map(MsgInfoVO::new)
                    .collect(Collectors.toList())
            );
        }
        return result;
    }

    @Override
    public MsgInfoVO fetchInMailInfo(String messageSn) {
        InMailRecord msg = inMailService.fetchBySn(messageSn);
        if (null == msg) {
            throw new ErrorDataException("消息有误");
        }
        return new MsgInfoVO(msg);
    }

    /**
     * 发送消息
     *
     * @param message
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendInMailMessage(SendInMailMessageDTO message) {
        LocalDateTime sendTime = LocalDateTime.now();
        InMailRecord inMail = message.transToInMail(sendTime);
        MessageRecord msg = message.transToMsg(sendTime);
        // 保存
        inMailService.save(inMail);
        msg.setMessageSn(inMail.getInMailSn());
        messageRecordService.save(msg);
    }

    @Override
    public boolean inMailModify(InMailModifyReq req) {
        InMailRecord inMail = inMailService.fetchBySn(req.getMessageSn());
        if (null == inMail) {
            throw new ErrorDataException("消息有误, 找不到该消息");
        }
        MessageRecord msg = messageRecordService.fetchBySn(req.getMessageSn());
        if (null == msg) {
            throw new ErrorDataException("消息有误, 找不到该消息");
        }
        InMailRecord updateInMail = req.tranToInMail();
        updateInMail.setId(inMail.getId());
        inMailService.updateById(updateInMail);
        MessageRecord update = req.tranToMessage();
        update.setId(msg.getId());
        return messageRecordService.updateById(update);
    }

    @Override
    public void modifyByDeleteSource(SendInMailMessageDTO message) {
        String querySn = message.getReqParams();
        if (StrUtil.isEmpty(querySn)) {
            return;
        }
        List<InMailRecord> inMailList = inMailService.list(Wrappers.<InMailRecord>query().lambda()
                .like(InMailRecord::getReqParams, querySn)
        );
        inMailList.forEach(inMail -> {
            String title = StrUtil.format("{}(已删除)", inMail.getTitle());
            MessageRecord msg = messageRecordService.fetchBySn(inMail.getInMailSn());
            if (null != msg) {
                MessageRecord updateMsg = new MessageRecord();
                updateMsg.setId(msg.getId());
                updateMsg.setTitle(title);
                messageRecordService.updateById(updateMsg);
            }
            InMailRecord update = new InMailRecord();
            update.setId(inMail.getId());
            update.setTitle(title);
            inMailService.updateById(update);
        });
    }
}
